{--------------------------XML Support Code-------------------------------
-------------------- Torque Game Engine - GUI Masser ---------------------
---------------------- Roll Game Team 2014 - BLumia ----------------------
   XML Support Code is a part for the GUI Masser to export TGE's GUI file
as a xml file or import a GUI-XML file in GUI Masser. 
-------------------------------------------------------------------------}
unit treexml;
// treeview to XML, XML to treeview by Glenn1234,
// may be used with proper credit given
interface
  uses msxml2_tlb, ComCtrls, dialogs, sysutils, ActiveX, guictrlclass;

type
TAGuiCtrls=array of TGuiCtrl;
// saves TTreeView as XML file.
TTreeViewToXML = class
  private
    doc: IXMLDOMDocument;
    FTree: TTreeView;

    procedure XMLPopulate(BaseNode: TTreeNode; DataItem: IXMLDOMelement);
  Public
    XMLguiCtrls: array of TGuiCtrl;
    Constructor Create(Tree: TTreeView;GuiCtrls:array of TGuiCtrl);
    procedure SaveToFile(filename: string);
    function getIdFormText(ts: string):Integer;
  end;

// loads TTreeView from XML file
TXMLToTreeView = class
  private
    doc: IXMLDOMDocument;
    FTree: TTreeView;

    procedure XMLLoad(BaseItem: TTreeNode; DataItem: IXMLDOMNode);
  Public
    i:integer;
    XMLguiCtrls:TAGuiCtrls;
    function XMLToTree(Tree: TTreeView; Const FileName: String):TAGuiCtrls;
  end;


implementation
constructor TTreeViewToXML.Create(Tree: TTreeView;GuiCtrls:array of TGuiCtrl);
var
  i:integer;
begin
  FTree := Tree;
  setlength(XMLGuiCtrls,length(GuiCtrls));
  for i:=1 to length(GuiCtrls) do begin
    XMLguiCtrls[i-1]:=TGuiCtrl.create;
    XMLguiCtrls[i-1]:=guiCtrls[i-1];
  end;
end;

function TTreeViewToXML.getIdFormText(ts: string):Integer;
begin
  ts:=copy(ts,1,pos(':',ts)-1);
  result:=strtoint(ts);
end;

procedure TTreeViewToXML.XMLPopulate(BaseNode: TTreeNode; DataItem: IXMLDOMelement);
var
  SubItem: IXMLDOMElement;
  selnode: TTreeNode;
  id:integer;
begin
  SelNode := BaseNode;
  while selnode <> nil do
    begin
      id:=getIdFormText(SelNode.Text);
      if SelNode.HasChildren then
        begin
          SubItem := doc.CreateElement('Group');
          SubItem.setAttribute('Funcname', XMLGuiCtrls[id].functionName);
          SubItem.setAttribute('Name', XMLGuiCtrls[id].name);
          SubItem.setAttribute('Profile', XMLGuiCtrls[id].profile);
          SubItem.setAttribute('Position', XMLGuiCtrls[id].viewPosition);
          SubItem.setAttribute('Extent', XMLGuiCtrls[id].viewExtent);
          SubItem.setAttribute('horizSizing', XMLGuiCtrls[id].viewHorizSizing);
          SubItem.setAttribute('vertSizing', XMLGuiCtrls[id].viewVertSizing);
          SubItem.setAttribute('visible', inttostr(ord(XMLGuiCtrls[id].visible)));
          SubItem.setAttribute('bitmap', XMLGuiCtrls[id].bitmap);
          DataItem.AppendChild(SubItem);
          XMLPopulate(SelNode.GetFirstChild, SubItem);
        end
      else
        begin
          SubItem := doc.CreateElement('Item');
          SubItem.setAttribute('Funcname', XMLGuiCtrls[id].functionName);
          SubItem.setAttribute('Name', XMLGuiCtrls[id].name);
          SubItem.setAttribute('Profile', XMLGuiCtrls[id].profile);
          SubItem.setAttribute('Position', XMLGuiCtrls[id].viewPosition);
          SubItem.setAttribute('Extent', XMLGuiCtrls[id].viewExtent);
          SubItem.setAttribute('horizSizing', XMLGuiCtrls[id].viewHorizSizing);
          SubItem.setAttribute('vertSizing', XMLGuiCtrls[id].viewVertSizing);
          SubItem.setAttribute('visible', inttostr(ord(XMLGuiCtrls[id].visible)));
          SubItem.setAttribute('bitmap', XMLGuiCtrls[id].bitmap);
          DataItem.AppendChild(SubItem);
        end;
      SelNode := SelNode.GetNextChild(SelNode);
    end;
end;

procedure TTreeViewToXML.SaveToFile(filename: string);
 var
   topnode: IXMLDOMElement;
   selnode: TTreeNode;
 begin
   //create DOM document instance
   CoInitialize(nil);
   doc := CoDOMDocument60.Create;
   doc.async := false;
//------------------------------------------------------------------------------
   topnode := doc.createElement('GUI_XML');//TreeView
   doc.appendChild(topnode);
   selnode := FTree.Items.GetFirstNode;
   XMLPopulate(SelNode, topnode);
   doc.save(FileName);
 end;

 procedure TXMLToTreeView.XMLLoad(BaseItem: TTreeNode; DataItem: IXMLDOMNode);
   var
     item1, item2: IXMLDOMNode;
     attr: IXMLDOMNamedNodeMap;
     CurrItem: TTreeNode;
   begin
     Item1 := DataItem;
     CurrItem := nil;   // compiler complains if I don't do this
     while Item1 <> nil do
       begin
         attr := item1.attributes;
         item2 := attr.nextNode;
         while item2 <> nil do
           begin
             CurrItem := FTree.Items.AddChild(BaseItem, Item2.NodeValue);
             //XMLGuiCtrls[i].setFunctionName(item1. )
             item2 := attr.nextNode;
           end;
         if item1.nodename = 'Group' then begin
           i:=i+1;
           XMLLoad(CurrItem, Item1.Get_firstChild);
         end;
         Item1 := Item1.Get_nextSibling;
       end;
   end;

   function TXMLToTreeView.XMLToTree(Tree: TTreeView;
                                     Const FileName: String):TAGuiCtrls;
    var
      item1: IXMLDOMNode;
    begin
     //create DOM document instance
      i:=0;
      doc := CoDOMDocument60.Create;
      doc.async := false;
      FTree := Tree;
     //------------------------------------------------------------------------------
      if doc.load(FileName) then
        begin
          FTree.Items.BeginUpdate;
          FTree.Items.Clear;
          Item1 := doc.documentElement.Get_firstChild;
          XMLLoad(nil, Item1);
          FTree.Items.EndUpdate;
        end
      else
        begin
          MessageDlg(Format ('Error loading XML document.'#13 +
                             'Error number: %d'#13 +
                             'Reason: %s'#13 +
                             'Line: %d'#13 +
                             'Column: %d', [doc.parseError.errorCode,
                             doc.parseError.reason,
                             doc.parseError.line,
                             doc.parseError.linePos]), mtError, [mbOK], 0);
        end;
        result:=XMLGuiCtrls;
    end;
 end.
